package com.nikkerball.apps.darkhorse.aspects;

import com.nikkerball.apps.darkhorse.dao.ChangeDao;
import com.nikkerball.apps.darkhorse.model.base.TouchableObject;
import com.nikkerball.apps.darkhorse.model.change.ChangeEvent;
import com.nikkerball.apps.darkhorse.model.change.ChangeValue;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.joda.time.DateTime;

import java.util.List;

/**
 * TODO: Document class
 *
 * @author marius (created on 2010-12-12)
 */
@Aspect
public class ChangeListener {

    // ----- instance fields -----

    private ChangeDao changeDao;

    // ----- public methods -----

    @Around("execution( * com.nikkerball.apps.darkhorse.dao.hibernate.BaseDaoHibernateImpl.add(..)) || " +
            " execution( * com.nikkerball.apps.darkhorse.dao.hibernate.BaseDaoHibernateImpl.delete(..)) ||" +
            " execution( * com.nikkerball.apps.darkhorse.dao.hibernate.BaseDaoHibernateImpl.update(..))")
    public Object changeMethods(ProceedingJoinPoint joinPoint)
            throws Throwable {
        // Do the event first (change event is saved only after the value has been changed)
        Object result = joinPoint.proceed();
        saveChangeEvent(joinPoint);
        return result;
    }

    public ChangeDao getChangeDao() {
        return this.changeDao;
    }

    public void setChangeDao(ChangeDao changeDao) {
        this.changeDao = changeDao;
    }

    // ----------

    private void saveChangeEvent(ProceedingJoinPoint joinPoint) {

        ChangeEvent changeEvent = new ChangeEvent();

        Object[] arguments = joinPoint.getArgs();

        String userName = (String) arguments[0];
        TouchableObject touchableObject = (TouchableObject) arguments[1];

        int objectId = touchableObject.getId();
        String objectType = touchableObject.getClass().getSimpleName();
        List<ChangeValue> changeValues = touchableObject.getChangeValues(changeEvent);

        String changeType = joinPoint.getSignature().getName();

        changeEvent.setCreateDate(new DateTime());
        changeEvent.setCreateUser(userName);
        changeEvent.setObjectId(objectId);
        changeEvent.setObjectType(objectType);
        changeEvent.setChangeType(changeType);
        changeEvent.setChangeValues(changeValues);

        getChangeDao().add(changeEvent);

    }
}
